<!DOCTYPE html>
<html lang="zh-Hans">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222"><meta name="generator" content="Hexo 6.2.0">


  <link rel="apple-touch-icon" sizes="180x180" href="/vhuichen.ico">
  <link rel="icon" type="image/png" sizes="32x32" href="/vhuichen.ico">
  <link rel="icon" type="image/png" sizes="16x16" href="/vhuichen.ico">
  <link rel="mask-icon" href="/vhuichen.ico" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css" integrity="sha256-AbA177XfpSnFEvgpYu1jMygiLabzPCJCRIBtR5jGc0k=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">

<script class="next-config" data-name="main" type="application/json">{"hostname":"vhuichen.github.io","root":"/","images":"/images","scheme":"Pisces","darkmode":false,"version":"8.13.0","exturl":false,"sidebar":{"position":"left","display":"display","padding":18,"offset":12},"copycode":{"enable":false,"style":null},"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"prism":false,"i18n":{"placeholder":"Searching...","empty":"We didn't find any results for the search: ${query}","hits_time":"${hits} results found in ${time} ms","hits":"${hits} results found"}}</script><script src="/js/config.js"></script>

    <meta name="description" content="什么是 KCP我们知道 UDP 是不可靠传输， 而 TCP 是可靠传输，但 TCP 本身也存在一些缺陷，例如：    连续丢包超时策略，连续丢包的RTO &#x3D; RTO * 2，这个参数好像无法改动 ；   丢包重传策略，在没有 SACK 之前，TCP在收到3个相同的 ack 时，才会触发丢包重传策略，并且会将后面所有的包全部重传（有些包其实已经收到了）；   退流控制策略， 为了保证网络传">
<meta property="og:type" content="article">
<meta property="og:title" content="KCP 协议">
<meta property="og:url" content="https://vhuichen.github.io/2022/05/NetworkProtocol/KCP/KCP/index.html">
<meta property="og:site_name" content="vhuichen">
<meta property="og:description" content="什么是 KCP我们知道 UDP 是不可靠传输， 而 TCP 是可靠传输，但 TCP 本身也存在一些缺陷，例如：    连续丢包超时策略，连续丢包的RTO &#x3D; RTO * 2，这个参数好像无法改动 ；   丢包重传策略，在没有 SACK 之前，TCP在收到3个相同的 ack 时，才会触发丢包重传策略，并且会将后面所有的包全部重传（有些包其实已经收到了）；   退流控制策略， 为了保证网络传">
<meta property="og:locale">
<meta property="article:published_time" content="2022-05-18T16:00:00.000Z">
<meta property="article:modified_time" content="2022-05-20T16:00:00.000Z">
<meta property="article:author" content="vhuichen">
<meta property="article:tag" content="KCP">
<meta name="twitter:card" content="summary">


<link rel="canonical" href="https://vhuichen.github.io/2022/05/NetworkProtocol/KCP/KCP/">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":false,"isPost":true,"lang":"zh-Hans","comments":true,"permalink":"https://vhuichen.github.io/2022/05/NetworkProtocol/KCP/KCP/","path":"2022/05/NetworkProtocol/KCP/KCP/","title":"KCP 协议"}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>KCP 协议 | vhuichen</title>
  






  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>
</head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="Toggle navigation bar" role="button">
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <p class="site-title">vhuichen</p>
      <i class="logo-line"></i>
    </a>
      <p class="site-subtitle" itemprop="description">记录、分享</p>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
    </div>
  </div>
</div>



<nav class="site-nav">
  <ul class="main-menu menu"><li class="menu-item menu-item-home"><a href="/" rel="section">Home</a></li><li class="menu-item menu-item-archives"><a href="/archives/" rel="section">Archives</a></li><li class="menu-item menu-item-about"><a href="/about/" rel="section">About</a></li>
  </ul>
</nav>




</div>
        
  
  <div class="toggle sidebar-toggle" role="button">
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
  </div>

  <aside class="sidebar">

    <div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          Table of Contents
        </li>
        <li class="sidebar-nav-overview">
          Overview
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
            <div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E4%BB%80%E4%B9%88%E6%98%AF-KCP"><span class="nav-number">1.</span> <span class="nav-text">什么是 KCP</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#KCP-%E5%8D%8F%E8%AE%AE%E5%A4%B4"><span class="nav-number">2.</span> <span class="nav-text">KCP 协议头</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#conv"><span class="nav-number">2.0.1.</span> <span class="nav-text">conv</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#cmd"><span class="nav-number">2.0.2.</span> <span class="nav-text">cmd</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#frg"><span class="nav-number">2.0.3.</span> <span class="nav-text">frg</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#wnd"><span class="nav-number">2.0.4.</span> <span class="nav-text">wnd</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#ts"><span class="nav-number">2.0.5.</span> <span class="nav-text">ts</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#sn"><span class="nav-number">2.0.6.</span> <span class="nav-text">sn</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#una"><span class="nav-number">2.0.7.</span> <span class="nav-text">una</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#len"><span class="nav-number">2.0.8.</span> <span class="nav-text">len</span></a></li></ol></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E9%83%A8%E5%88%86%E4%BB%A3%E7%A0%81"><span class="nav-number">3.</span> <span class="nav-text">部分代码</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#%E5%88%9B%E5%BB%BA-KCP-%E5%AF%B9%E8%B1%A1"><span class="nav-number">3.1.</span> <span class="nav-text">创建 KCP 对象</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#%E6%A8%A1%E5%BC%8F%E9%85%8D%E7%BD%AE"><span class="nav-number">3.2.</span> <span class="nav-text">模式配置</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#%E5%88%86%E7%89%87%E5%8C%85%E5%9B%9E%E8%B0%83"><span class="nav-number">3.3.</span> <span class="nav-text">分片包回调</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#%E6%9B%B4%E6%96%B0%E7%8A%B6%E6%80%81"><span class="nav-number">3.4.</span> <span class="nav-text">更新状态</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#%E5%8F%91%E9%80%81%E6%95%B0%E6%8D%AE"><span class="nav-number">3.5.</span> <span class="nav-text">发送数据</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#%E6%8E%A5%E6%94%B6%E6%95%B0%E6%8D%AE"><span class="nav-number">3.6.</span> <span class="nav-text">接收数据</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%8F%91%E9%80%81%E6%B5%81%E7%A8%8B"><span class="nav-number">4.</span> <span class="nav-text">发送流程</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%8E%A5%E6%94%B6%E6%B5%81%E7%A8%8B"><span class="nav-number">5.</span> <span class="nav-text">接收流程</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#KCP%E7%89%B9%E7%82%B9"><span class="nav-number">6.</span> <span class="nav-text">KCP特点</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%80%BB%E7%BB%93"><span class="nav-number"></span> <span class="nav-text">总结</span></a></div>
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author site-overview-item animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="vhuichen"
      src="/images/vhuichen.jpg">
  <p class="site-author-name" itemprop="name">vhuichen</p>
  <div class="site-description" itemprop="description"></div>
</div>
<div class="site-state-wrap site-overview-item animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
        <a href="/archives/">
          <span class="site-state-item-count">78</span>
          <span class="site-state-item-name">posts</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
          <a href="/categories/">
        <span class="site-state-item-count">11</span>
        <span class="site-state-item-name">categories</span></a>
      </div>
      <div class="site-state-item site-state-tags">
          <a href="/tags/">
        <span class="site-state-item-count">86</span>
        <span class="site-state-item-name">tags</span></a>
      </div>
  </nav>
</div>



        </div>
      </div>
    </div>
  </aside>
  <div class="sidebar-dimmer"></div>


    </header>

    
  <div class="back-to-top" role="button" aria-label="Back to top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


    <div class="main-inner post posts-expand">


  


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="zh-Hans">
    <link itemprop="mainEntityOfPage" href="https://vhuichen.github.io/2022/05/NetworkProtocol/KCP/KCP/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/vhuichen.jpg">
      <meta itemprop="name" content="vhuichen">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="vhuichen">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="KCP 协议 | vhuichen">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          KCP 协议
        </h1>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">Posted on</span>

      <time title="Created: 2022-05-19 00:00:00" itemprop="dateCreated datePublished" datetime="2022-05-19T00:00:00+08:00">2022-05-19</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar-check"></i>
      </span>
      <span class="post-meta-item-text">Edited on</span>
      <time title="Modified: 2022-05-21 00:00:00" itemprop="dateModified" datetime="2022-05-21T00:00:00+08:00">2022-05-21</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">In</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E7%BD%91%E7%BB%9C%E5%8D%8F%E8%AE%AE/" itemprop="url" rel="index"><span itemprop="name">网络协议</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
        <h3 id="什么是-KCP"><a href="#什么是-KCP" class="headerlink" title="什么是 KCP"></a>什么是 KCP</h3><p>我们知道 UDP 是不可靠传输， 而 TCP 是可靠传输，但 TCP 本身也存在一些缺陷，例如：  </p>
<ol>
<li>连续丢包超时策略，连续丢包的RTO &#x3D; RTO * 2，这个参数好像无法改动 ；  </li>
<li>丢包重传策略，在没有 SACK 之前，TCP在收到3个相同的 ack 时，才会触发丢包重传策略，并且会将后面所有的包全部重传（有些包其实已经收到了）；  </li>
<li>退流控制策略， 为了保证网络传输效率，TCP有发送窗口、接收窗口、慢启动、丢包退让策略，这样使得数据传输在一定程度上被阻塞了；  </li>
<li>延时ack</li>
<li>。。。。。。</li>
</ol>
<p>那除了 TCP 以外还有什么方式可以实现可靠性传输呢？就是 KCP ，KCP 本身只是一个算法实现，平台无关，并没有指定传输协议，所以通过 KCP + UDP 就可以实现跟 TCP 一样的可靠性传输；</p>
<h3 id="KCP-协议头"><a href="#KCP-协议头" class="headerlink" title="KCP 协议头"></a>KCP 协议头</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">0                 4     5     6          8  (BYTE)</span><br><span class="line">+-----------------+-----+-----+----------+  0</span><br><span class="line">|      conv       | cmd | frg |   wnd    |</span><br><span class="line">+-----------------+-----+-----+----------+  8</span><br><span class="line">|       ts        |         sn           |</span><br><span class="line">+-----------------+----------------------+  16</span><br><span class="line">|       una       |         len          |</span><br><span class="line">+-----------------+----------------------+  24</span><br><span class="line">|                                        |</span><br><span class="line">|            DATA (optional)             |</span><br><span class="line">|                                        |</span><br><span class="line">+----------------------------------------+</span><br></pre></td></tr></table></figure>
<h5 id="conv"><a href="#conv" class="headerlink" title="conv"></a>conv</h5><p>连接号，用于表示属于哪个连接  </p>
<span id="more"></span>
<h5 id="cmd"><a href="#cmd" class="headerlink" title="cmd"></a>cmd</h5><p>命令类型</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">const IUINT32 IKCP_CMD_PUSH = 81; // cmd: push data</span><br><span class="line">const IUINT32 IKCP_CMD_ACK  = 82; // cmd: ack</span><br><span class="line">const IUINT32 IKCP_CMD_WASK = 83; // cmd: window probe (ask) 请求告知窗口大小</span><br><span class="line">const IUINT32 IKCP_CMD_WINS = 84; // cmd: window size (tell) 告知窗口大小</span><br></pre></td></tr></table></figure>
<h5 id="frg"><a href="#frg" class="headerlink" title="frg"></a>frg</h5><p>分片，相当于 TCP 的拆包</p>
<h5 id="wnd"><a href="#wnd" class="headerlink" title="wnd"></a>wnd</h5><p>窗口大小</p>
<h5 id="ts"><a href="#ts" class="headerlink" title="ts"></a>ts</h5><p>时间戳，计算数据包往返时间？</p>
<h5 id="sn"><a href="#sn" class="headerlink" title="sn"></a>sn</h5><p>当前包的序列号</p>
<h5 id="una"><a href="#una" class="headerlink" title="una"></a>una</h5><p>下一个可接收的序列号，相当于 TCP 的 ACK</p>
<h5 id="len"><a href="#len" class="headerlink" title="len"></a>len</h5><p>包长度</p>
<h3 id="部分代码"><a href="#部分代码" class="headerlink" title="部分代码"></a>部分代码</h3><h4 id="创建-KCP-对象"><a href="#创建-KCP-对象" class="headerlink" title="创建 KCP 对象"></a>创建 KCP 对象</h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">/*</span><br><span class="line">conv ：表示会话编号</span><br><span class="line">user ：回调</span><br><span class="line">*/</span><br><span class="line">ikcpcb* ikcp_create(IUINT32 conv, void *user)</span><br></pre></td></tr></table></figure>
<h4 id="模式配置"><a href="#模式配置" class="headerlink" title="模式配置"></a>模式配置</h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">/*</span><br><span class="line">nodelay ：是否启用不延迟ack模式，0：不启用，1：启用</span><br><span class="line">interval ：协议工作间隔，40ms</span><br><span class="line">resend ：快速重传，0：关闭，2：收到 2次 ACK 则直接重传</span><br><span class="line">nc ：退流控制，0：不关闭，1：关闭</span><br><span class="line">*/</span><br><span class="line">int ikcp_nodelay(ikcpcb *kcp, int nodelay, int interval, int resend, int nc)</span><br></pre></td></tr></table></figure>

<h4 id="分片包回调"><a href="#分片包回调" class="headerlink" title="分片包回调"></a>分片包回调</h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">// 发送数据包回调，这里面的包就是已经分片的了；一般交给 UDP 发送</span><br><span class="line">int c_udp_output(const char * buf, int len, ikcpcb * kcp, void * user)</span><br></pre></td></tr></table></figure>

<h4 id="更新状态"><a href="#更新状态" class="headerlink" title="更新状态"></a>更新状态</h4><p>状态更新是由外部实现的，在合适的时机触发，同时需要一个定时器触发</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">//current 表示时间戳</span><br><span class="line">void ikcp_update(ikcpcb *kcp, IUINT32 current)</span><br></pre></td></tr></table></figure>

<h4 id="发送数据"><a href="#发送数据" class="headerlink" title="发送数据"></a>发送数据</h4><p>用户发送数据包，方法内会将数据分片，存入待发送队列中</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">int ikcp_send(ikcpcb *kcp, const char *buffer, int len)</span><br></pre></td></tr></table></figure>

<h4 id="接收数据"><a href="#接收数据" class="headerlink" title="接收数据"></a>接收数据</h4><p>所有从UDP传回来的数据</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">int ikcp_input(ikcpcb *kcp, const char *data, long size)</span><br></pre></td></tr></table></figure>
<p>返回用户需要的数据包</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">int ikcp_recv(ikcpcb *kcp, char *buffer, int len)</span><br></pre></td></tr></table></figure>

<h3 id="发送流程"><a href="#发送流程" class="headerlink" title="发送流程"></a>发送流程</h3><ol>
<li>调用 ikcp_send，分片，并将分片后的数据存入待发送队列 snd_queue</li>
<li>等待状态更新 ikcp_update，这个间隔就是初始化时的间隔</li>
<li>间隔到来时，调用 ikcp_flush ，内部会将待发送队列的数据移动到发送队列（snd_buf）中，有窗口大小限制，然后将发送队列中的数据全部调用初始化时设置的回调函数 c_udp_output ，也就是交给 UDP 处理</li>
</ol>
<h3 id="接收流程"><a href="#接收流程" class="headerlink" title="接收流程"></a>接收流程</h3><ol>
<li>UDP 接收到数据包</li>
<li>调用 ikcp_input 解析数据包，更新接收窗口大小，更新 una，根据una，删除 snd_buf 中已确认分片，将 sn + ts 存放在 acklist 中；判断是否需要重传，是否需要更新发送窗口；</li>
<li>调用 ikcp_parse_data 方法，将包存放在 rcv_buf 中，并将 rcv_buf 中完整的数据移动到 rcv_queue 中</li>
<li>调用 ikcp_recv 合包，并将完整的包取出来，返回给上层业务</li>
</ol>
<blockquote>
<p>rcv_buf 是不连续的，rcv_queue 的数据是连续的</p>
</blockquote>
<h3 id="KCP特点"><a href="#KCP特点" class="headerlink" title="KCP特点"></a>KCP特点</h3><ol>
<li>连续超时RTO &#x3D; RTO * 1.5</li>
<li>ack可以设置成无延迟的</li>
<li>可以设置快速重传模式</li>
<li>选择重传</li>
<li>可以配置非退流控制</li>
</ol>
<h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>KCP 自己实现了 ARQ 协议；相当于一个定制化的 TCP，弱网下传输速度更快，流量换时间；也跟 HTTP3.0 的实现方式很相似。</p>

    </div>

    
    
    

    <footer class="post-footer">
          <div class="post-tags">
              <a href="/tags/KCP/" rel="tag"># KCP</a>
          </div>

        

          <div class="post-nav">
            <div class="post-nav-item">
                <a href="/2022/04/iOS/libffi%E6%8E%A2%E7%A9%B6%20/" rel="prev" title="libffi 探究">
                  <i class="fa fa-chevron-left"></i> libffi 探究
                </a>
            </div>
            <div class="post-nav-item">
            </div>
          </div>
    </footer>
  </article>
</div>






</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">


<div class="copyright">
  &copy; 2015 – 
  <span itemprop="copyrightYear">2022</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">vhuichen</span>
</div>
  <div class="powered-by">Powered by <a href="https://hexo.io/" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/pisces/" rel="noopener" target="_blank">NexT.Pisces</a>
  </div>

    </div>
  </footer>

  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/next-boot.js"></script>

  





  





</body>
</html>
